// 作业1

// 简述bind、call、apply的作用及区别。

// 关于bind、call、apply函数，他们主要用来改变this指向的

// 一。bind用法

// bind作用是只修改this指向，但不会立即执行fn;
// 会返回一个修改了this指向后的fn，需要调用才会执行
// bind的传参和call相同

let user={
    name:"xxxxxx",
    age:18,
    say:function(job,hobby){
       console.log("我叫"+this.name+",今年"+this.age+",工作："+job+',爱好：'+hobby);
    }
}

user.say("学生","听音乐")//我叫xxxxxx,今年18,工作：学生,爱好：听音乐

let obj={
    name:"liu",
    age:12
}

user.say.bind(obj,"无业","吃");//无输出结果
user.say.bind(obj,"无业","吃")();//我叫liu,今年12,工作：无业,爱好：吃

// 二、call的用法
// 调用fn.call时会将fn中的this指向修改为传入的第一个参数thisArg；
// 将后面的参数传入给fn,并立即执行函数fn。

user.say.call(obj,"无业","吃");//我叫liu,今年12,工作：无业,爱好：吃

// 三、apply用法
//fn.apply的作用和call相同；
// 修改this指向，并立即执行fn。
// 区别在于传参形式不同，apply接受两个参数，
// 第一个参数是要指向的this对象，
// 第二个参数是一个数组，
// 数组里面的元素会被展开传入fn,作为fn的参数。
user.say.apply(obj,["无业","吃"]);//我叫liu,今年12,工作：无业,爱好：吃

// bind、call、apply的区别

// 1、相同点
// 三个都是用于改变this指向；
// 接收的第一个参数都是this要指向的对象；
// 都可以利用后续参数传参。

// 2、不同点
// call和bind传参相同，多个参数依次传入的；
// apply只有两个参数，第二个参数为数组；
// call和apply都是对函数进行直接调用，而bind方法不会立即调用函数，而是返回一个修改this后的函数。

// 作业2

// 简述什么是递归函数？

// 递归就是一个函数在它的函数体内调用它自身。
// 执行递归函数将反复调用其自身，每调用一次就进入新的一层。
// 递归函数必须有结束条件。 

// 作业3

// 简述深拷贝和浅拷贝，手写一个实现深拷贝的函数。

// 深拷贝出来的对象就是完完全全的新对象，不管是对象本身(id)，还是对象中包含的子对象，都和原始对象不一样；
// 浅拷贝出来的对象就是外新内旧的对象，对象本身(id)和原始对象完全不同，但是子对象和原始对象的子对象是一样的。

var obj1={
    name:"jan",
    age: 20,
    dog:{ 
        fname: "猫",
        head:3,
        age: 3,
    }
}
let newobj ={} ; //创建一个空对象
function arr(a,b){//遍历函数,传入参数
   for(var key in a){
        var item = a[key];
        if(item instanceof Array) {//判断item是不是数组
            b[key] = item;
            arr(item, b[key]);
        }else if(item instanceof Object){//判断item是不是对象
            b[key]= item;
            arr (item, b[key]);
        }else {
            b[key]= item;
        }
    }
}

arr (obj1, newobj);
console.log(obj1,newobj); 